import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { isEmail, isMobilePhone } from 'class-validator';
import { ConfigService } from 'nestjs-config';
import { Repository, SelectQueryBuilder } from 'typeorm';
import { ToolsService } from '../shared/services/tools/tools.service';
import { UserEntity } from '../user/entities/user.entity';
import { AuthDto } from './dto/auth.dto';
import { TokenEntity } from './entities/token.entity';
import { UserLastLoginEntity } from './entities/user.last.login.entity';

import * as moment from 'moment';

@Injectable()
export class AuthService {
  constructor(
    @InjectRepository(UserEntity)
    private readonly userRepository: Repository<UserEntity>,
    @InjectRepository(TokenEntity)
    private readonly tokenRepository: Repository<TokenEntity>,
    @InjectRepository(UserLastLoginEntity)
    private readonly userLastLoginRepository: Repository<UserLastLoginEntity>,
    private readonly toolsService: ToolsService,
    private readonly configService: ConfigService,
  ) {}
  /**
   * @Author: laotongshu
   * @Date: 2022-09-21 18:23:22
   * @LastEditors: laotongshu
   * @Description: 登录
   * @param {AuthDto} authDto
   * @return {*}
   */
  async login(authDto: AuthDto) {
    // 用户名有可能是手机号，邮箱或者用户名
    const { username, password } = authDto;
    let findUser = null;
    const queryBuilder = this.queryLoginBuilder;
    // 根据手机号码查询
    if (isMobilePhone(username, 'zh-CN')) {
      findUser = await queryBuilder
        .where('user.mobile = :mobile', { mobile: username })
        .getRawOne();
    } else if (isEmail(username)) {
      findUser = await queryBuilder.where('user.email = :email', { email: username }).getRawOne();
    } else {
      findUser = await queryBuilder
        .where('user.username = :username', { username: username })
        .getRawOne();
    }
    console.log('2022-09-21 11:19:30', findUser);
    if (findUser && findUser.password === password) {
      // 记录最后的登录时间
      // 生成token
      const token = this.toolsService.getToken();
      const { id, username, email, mobile, isSuper } = findUser;
      // 获取过期时间
      const tokenExpire = this.configService.get('admin.tokenExpire');
      const userToken = {
        userId: id,
        token,
        expireTime: moment().add(tokenExpire, 'day').format('YYYY-MM-DD HH:mm:ss'),
      };
      console.log('2022-09-22 20:16:05', token);
      // 先判断之前是否有记录，有记录就更新，没记录就创建
      const userTokenResult = await this.tokenRepository.findOne({
        where: { userId: id },
        select: ['id'],
      });
      // 生成token存储到token表;
      if (userTokenResult?.id) {
        // 更新
        await this.tokenRepository.update({ id: userTokenResult.id }, userToken);
      } else {
        const userTokenSave = await this.tokenRepository.create(userToken);
        await this.tokenRepository.save(userTokenSave);
      }
      // 返回给前端
      return {
        token,
        username,
        email,
        mobile,
        isSuper,
      };
    } else {
      throw new HttpException('用户名或密码错误', HttpStatus.OK);
    }
  }

  /**
   * @Author: laotongshu
   * @Date: 2022-09-21 18:24:22
   * @LastEditors: laotongshu
   * @Description: 公共的查询部分
   * @param {Object} {}
   * @return {*}
   */
  private get queryLoginBuilder(): SelectQueryBuilder<UserEntity> {
    return this.userRepository
      .createQueryBuilder('user')
      .select('user.id', 'id')
      .addSelect('user.password', 'password')
      .addSelect('user.username', 'username')
      .addSelect('user.mobile', 'mobile')
      .addSelect('user.email', 'email')
      .addSelect('user.isSuper', 'isSuper');
  }
}
